package hos.util.utils;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import hos.java.compat.NetConstant;
import hos.java.convert.NetConverter;
import hos.java.util.AnyUtils;
import hos.java.util.StringUtils;

/**
 * <p>Title: JsonUtils </p>
 * <p>Description: Json转换 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2022/5/12 22:15
 */
public class JsonUtils {

    public static String toJson(List<Map<String, Object>> mapList) {
        if (mapList == null || mapList.isEmpty()) {
            return "[]";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (Map<String, Object> map : mapList) {
            String json = toJson(map);
            sb.append(json);
        }
        sb.append("]");
        return sb.toString();
    }


    @SuppressWarnings("unchecked")
    public static String toJson(Map<String, Object> mapList) {
        if (mapList == null || mapList.isEmpty()) {
            return "{}";
        }
        StringBuilder sb = new StringBuilder();
        sb.append("{");
        for (String key : mapList.keySet()) {
            Object object = mapList.get(key);
            Object value = object;
            if (object instanceof List) {
                value = toJson((List<Map<String, Object>>) object);
            } else if (object instanceof Map) {
                value = toJson((Map<String, Object>) object);
            }
            sb.append(key).append(":'").append(value).append("'").append(",");
        }
        sb.deleteCharAt(sb.lastIndexOf(","));
        sb.append("}");
        return sb.toString();
    }

    public static String requireJson(Object response) throws Exception {
        return requireJson(response, "200", "code", "msg");
    }

    public static String requireJson(Object response, String success) throws Exception {
        return requireJson(response, success, "code", "msg");
    }

    public static String requireJson(Object response, String success, String code) throws Exception {
        return requireJson(response, success, code, "msg");
    }

    public static String requireJson(Object response, String success, String code, String message) throws IOException {
        if (response == null) {
            return null;
        }
        String jsonResponse = AnyUtils.empty(response);
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (StringUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                return jsonResponse;
            } else { // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, NetConstant.SERVER_DATA_ERROR);
                throw new NetConverter.ConvertException(srvCode, errorMessage); // 将业务错误码作为tag传递
            }
        } catch (JSONException e1) { // 固定格式JSON分析失败直接解析JSON
            return jsonResponse;
        }
    }


    public static String requireJsonData(Object response) throws Exception {
        return requireJsonData(response, "200", "code", "msg", "data");
    }


    public static String requireJsonData(Object response, String success) throws Exception {
        return requireJsonData(response, success, "code", "msg", "data");
    }


    public static String requireJsonData(Object response, String success, String data) throws Exception {
        return requireJsonData(response, success, "code", "msg", data);
    }


    public static String requireJsonData(Object response, String success, String code, String data) throws Exception {
        return requireJsonData(response, success, code, "msg", data);
    }

    public static String requireJsonData(Object response, String success, String code, String message, String data) throws IOException {
        if (response == null) {
            return null;
        }
        String jsonResponse = AnyUtils.empty(response);
        try {
            JSONObject json = new JSONObject(jsonResponse); // 获取JSON中后端定义的错误码和错误信息
            String srvCode = json.getString(code);
            if (StringUtils.equals(srvCode, success)) { // 对比后端自定义错误码
                Object resultData = json.get(data);
                if (resultData instanceof JSONObject) {
                    return ((JSONObject) resultData).toString();
                }
                if (resultData instanceof JSONArray) {
                    return ((JSONArray) resultData).toString();
                }
                return AnyUtils.empty(resultData);
            } else { // 错误码匹配失败, 开始写入错误异常
                String errorMessage = json.optString(message, NetConstant.SERVER_DATA_ERROR);
                throw new NetConverter.ConvertException(srvCode, errorMessage); // 将业务错误码作为tag传递
            }
        } catch (JSONException e1) { // 固定格式JSON分析失败直接解析JSON
            return jsonResponse;
        }
    }

    public static Map<String, Object> parseJsonObject(JSONObject json) {
        Map<String, Object> map = new HashMap<>();
        Iterator<String> rootKey = json.keys();
        //迭代是反复内容,使用循环实现,循环的条件,集合中没元素, hasNext()返回了false
        while (rootKey.hasNext()) {
            String key = rootKey.next();
            try {
                Object value = json.get(key);
                if (value instanceof JSONObject) {
                    map.put(key, parseJsonObject((JSONObject) value));
                } else if (value instanceof JSONArray) {
                    map.put(key, parseJsonArray((JSONArray) value));
                } else {
                    map.put(key, value);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return map;
    }

    public static List<Map<String, Object>> parseJsonArray(JSONArray json) {
        List<Map<String, Object>> list = new ArrayList<>();
        int length = json.length();
        for (int i = 0; i < length; i++) {
            try {
                Object value = json.get(i);
                if (value instanceof JSONObject) {
                    list.add(parseJsonObject((JSONObject) value));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

}
